package com.smartmail.receiving;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.smartmail.accounts.Accounts;
import com.smartmail.accounts.MailAccount;
import com.smartmail.mailing.MailMessage;

/**
 * Main class responsible for receiving issues like DB managers,
 * adding, deleting mail accounts from Receving component.
 * 
 * @author Tomek
 * 
 */

public class Receiving {

	/**
	 * Initialize Receiving component in application.
	 * Create Incoming Database Manager for every account in application.
	 * 
	 * @param context - application context.
	 */
	public static void init(Context context) {

		if (_managers == null) {

			_managers = new HashMap<Integer, IncomingMailDBManager>();

		}

		_context = context;
		ReceivingRequestsHandler.init(_context);

		
		//create manager and queue for every mail account in program
		for (MailAccount account : Accounts.getAccountList()) {

			addManager(account);
		}
	}
	
	/**
	 * This method remove all messages stored on SD card
	 * binded with this mailAccount, also removes incoming mail's database for this account
	 * and kills RetrievalService's AbstractRetrievalThread listening for new messages sent to this account.
	 * 
	 * @param mailAccount - mail account which is wanted to be delete from
	 * SmarMail application. 
	 */
	public static void deleteAccountFromReceiving(MailAccount mailAccount){
		
		RetrievalService.deleteRetrievalThread(mailAccount);
		IncomingMailDBManager dbManager = getDBManager(mailAccount);
		
		// delete all files from  SD card
		// and delete all data from database
		for(MailMessage m : dbManager.getAllMessages()){
			
			InternalStorageUtility.deleteMessageFromSDCard(m);
		}
		
		dbManager.deleteDatabase();
		_managers.remove(mailAccount.getAccountID());
	}

	/**
	 * Get Incoming Mails' DB manager
	 * 
	 * @param account - MailAccount which DB manager is wanted to bring back
	 * @return - Incoming Mail's Database Manager
	 */
	public static IncomingMailDBManager getDBManager(MailAccount account) {

		IncomingMailDBManager manager = _managers.get(account.getAccountID());

		return manager;
	}

	/**
	 * Get Incoming Mails' DB manager
	 * 
	 * @param accountID - MailAccount ID which DB manager is wanted to bring back
	 * @return - Incoming Mail's Database Manager
	 */
	public static IncomingMailDBManager getDBManager(Integer accountID) {

		IncomingMailDBManager manager = _managers.get(accountID);

		return manager;
	}


	/**
	 * Create Incoming DB manager for this account.
	 * Send Intent about new account creation. 
	 * (for RetrievelService, to start execution of new
	 * AbstractRetrievalThread)
	 * 
	 * @param account - MailAccount which is added to application
	 */
	public static void addAcountToReceiving(MailAccount account) {

		addManager(account);
		
		Log.d(_logTag,"Receiving : addAccount id :" + account.getAccountID());

		Intent intent = new Intent(Accounts.NEW_ACCOUNT_ADDED_ACTION);
		intent.putExtra(Accounts.NEW_ACCOUNT_ADDED_ID, account.getAccountID());
		_context.sendBroadcast(intent);

	}
	
	/**
	 * Add Incoming Mail DB manager for this account
	 * 
	 * @param account -  MailAccount which is added to application
	 */
	private static void addManager(MailAccount account) {

		if (_managers.containsKey(account.getAccountID()))
			return;

		String dbName = account.getMailAddress() + "_" + account.getAccountID()
				+ ".db";
		IncomingMailDBManager manager = new IncomingMailDBManager(_context,
				dbName);

		_managers.put(account.getAccountID(), manager);
	}
	
	/**
	 * log tag for logging purposes
	 */
	private static String _logTag = "com.smartmail.receiving";
	
	/**
	 * Map containing Incoming Database's managers for all mail accounts
	 * registered in application.
	 * 
	 * Key - account ID 
	 * Value - IncomingMailDBManager
	 */
	private static Map<Integer, IncomingMailDBManager> _managers;

	/**
	 * Application context.
	 */
	private static Context _context;
	
	
	
	/******************* INTENT TYPES *************************/
	/**
	 * Intent which will be sent when new mail arrives to store
	 */
	public static final String NEW_MESSAGE_ARRIVED_INTENT = "com.smartmail.MESSAGE_INFO_INTENT_";
	
	/**
	 * Intent which will be sent when message content's are downloaded from server
	 */
	public static final String MESSAGE_DOWNLOADED_INTENT = "com.smartmail.MESSAGE_DOWNLOADED_INTENT_";
	
	/**
	 * Intent which will be sent when after checking mailbox, new messages are indicated
	 */
	public static final String NOTIFICATION_NEW_EMAILS_INTENT = "com.smartmail.NOTIFICATIONS_NEW_EMAILS_INTENT";

	/**
	 * Intent which will be sent when message is deleted from device
	 */
	public static final String MESSAGE_DELETED_INTENT = "com.smartmail.MESSAGE_DELETED_INTENT";
	
	/**
	 * Intent which will be sent when message content's are unavailable on server
	 */
	public static final String MESSAGE_UNAVAILABLE_INTENT = "com.smartmail.MESSAGE_UNAVAILABLE_INTENT";
	
	/**
	 * extra information sent with intent, this helps identify to which store
	 * mail was sent and helps to identify mail in database (id)
	 */
	public static final String MAIL_INFO_HASH = "_MAIL_INFO_HASH";
	public static final String MAIL_INFO_ACCOUNT_ID = "_MAIL_INFO_ACCOUNT_ID_";
	public static final String NUMBER_OF_NEW_EMAILS = "NUMBER_OF_NEW_EMAILS";
	

}
